package com.hsjk.szwj.module.mp.controller.app;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hsjk.szwj.framework.common.exception.ServiceException;
import com.hsjk.szwj.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.hsjk.szwj.framework.common.pojo.CommonResult;
import com.hsjk.szwj.framework.security.core.annotations.PreAuthenticated;
import com.hsjk.szwj.framework.tenant.core.context.TenantContextHolder;
import com.hsjk.szwj.module.member.api.user.dto.MemberCreateReqDTO;
import com.hsjk.szwj.module.mp.controller.app.vo.AppAuthLoginRespVO;
import com.hsjk.szwj.module.mp.dal.dataobject.MpConfigDO;
import com.hsjk.szwj.module.mp.service.IMpService;
import com.hsjk.szwj.module.system.api.tenant.TenantApi;
import com.hsjk.szwj.module.system.api.tenant.dto.TenantRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static com.hsjk.szwj.framework.common.pojo.CommonResult.success;

/**
 * @author chenjiawei
 * @desc
 * @Date 2023/08/08 16:44
 **/
@Tag(name = "应用端 - 微信公众号授权相关接口")
@RestController
@RequestMapping("/wx-auth")
@Validated
@Slf4j
public class AppMpAuthController {
    @Resource
    private IMpService mpService;
    @Resource
    private TenantApi tenantApi;

    @Value("${szwj.base-url}")
    private String baseUrl;

    @RequestMapping("/login")
    public void wxLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Long tenantId = TenantContextHolder.getTenantId();
        TenantRespDTO tenantInfo = tenantApi.getTenantInfo(tenantId);
        if (ObjectUtil.isNotNull(tenantInfo)) {
            baseUrl = tenantInfo.getDomain();
        }
        String url = baseUrl + "/h5/#/login";
        String inviterId = request.getParameter("uid");
        if (ObjectUtil.isNull(inviterId)) {
            inviterId = "";
        }
        MpConfigDO systemMp = mpService.getMpByTenantId(tenantId);
        log.info("systemMp:" + JSONUtil.parseObj(systemMp));
        if (ObjectUtil.isNotNull(systemMp)) {
            //请求获取code的回调地址
            //用线上环境的域名或者用内网穿透，不能用ip
            String callBack = baseUrl + "/prod/app-api/wx-auth/callback?tenantId="
                    + tenantId;

            //请求地址
            url = "https://open.weixin.qq.com/connect/oauth2/authorize" +
                    "?appid=" + systemMp.getAppId() +
                    "&redirect_uri=" + URLUtil.encode(callBack) +
                    "&response_type=code" +
                    "&scope=snsapi_userinfo" +
                    "&state=" + inviterId +
                    "#wechat_redirect";
        }
        //重定向
        response.sendRedirect(url);
    }

    @RequestMapping("/callback")
    public void wxCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String code = request.getParameter("code");
        String tenantId = request.getParameter("tenantId");
        String inviterId = request.getParameter("state");
        log.info("wxCallBack:inviterId" + inviterId);
        MpConfigDO systemMp = mpService.getMpByTenantId(Long.valueOf(tenantId));
        AppAuthLoginRespVO appAuthLoginRespVO;
        String redirectUrl = baseUrl + "/h5/#/login";
        if (ObjectUtil.isNotNull(systemMp)) {
            TenantContextHolder.setTenantId(Long.valueOf(tenantId));
            //获取access_token
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                    "?appid=" + systemMp.getAppId() +
                    "&secret=" + systemMp.getAppSecret() +
                    "&code=" + code +
                    "&grant_type=authorization_code";
            String body = HttpUtil.createGet(url).execute().body();
            log.info("wxCallBack:body" + body);
            JSONObject bodyObject = JSONUtil.parseObj(body);
            String openId = bodyObject.getStr("openid");
            String unionId = bodyObject.getStr("unionid");
            String accessToken = bodyObject.getStr("access_token");
            //请求获取userInfo
            String infoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                    "?access_token=" + accessToken +
                    "&openid=" + openId +
                    "&lang=zh_CN";
            String resultInfo = HttpUtil.createGet(infoUrl).execute().body();
            //此时已获取到userInfo，再根据业务进行处理
            log.error("wxCallBack:resultInfo" + resultInfo);
            JSONObject resultObject = JSONUtil.parseObj(resultInfo);
            String nickName = resultObject.getStr("nickname");
            String headImgUrl = resultObject.getStr("headimgurl");
            MemberCreateReqDTO reqDTO = new MemberCreateReqDTO();
            reqDTO.setNickname(nickName);
            reqDTO.setAvatar(headImgUrl);
            reqDTO.setOpenId(openId);
            reqDTO.setUnionId(unionId);
            reqDTO.setTenantId(Long.valueOf(tenantId));
            if (ObjectUtil.isNotEmpty(inviterId)) {
                reqDTO.setInviterMemberId(Long.valueOf(inviterId));
            }
            appAuthLoginRespVO = mpService.wxCallbackHandle(reqDTO);
            redirectUrl = baseUrl + "/h5/#/login"
                    + "?mid=" + appAuthLoginRespVO.getMemberId()
                    + "&token=" + appAuthLoginRespVO.getAccessToken();
        }
        try {
            // 重定向到登录，自动跳转首页
            response.sendRedirect(redirectUrl);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode()
                    , "【微信回调错误】重定向地址错误");
        }
    }

    @GetMapping(value = "/create-qr-code")
    @Operation(summary = "生成公众号二维码")
    @PreAuthenticated
    public CommonResult<String> createQrCode(@RequestParam String sceneStr) {
        return success(mpService.createMpQrCode(sceneStr));
    }

    @GetMapping(value = "/get-short-url")
    @Operation(summary = "获取公众号二维码短连接")
    @PreAuthenticated
    public CommonResult<String> getShortUrl(@RequestParam String ticket) {
        return success(mpService.getMpQrCodShortUrl(ticket));
    }

    @GetMapping(value = "/get-long-url")
    @Operation(summary = "获取公众号二维码长连接")
    @PreAuthenticated
    public CommonResult<String> getLongUrl(@RequestParam String ticket) {
        return success(mpService.getMpQrCodLongUrl(ticket));
    }
}
